home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / vim / src / help.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  4KB  |  166 lines

  1. /* vi:ts=4:sw=4
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Read the file "credits.txt" for a list of people who contributed.
  6.  * Read the file "uganda.txt" for copying and usage conditions.
  7.  */
  8.  
  9. /*
  10.  * help.c: display help from the vim.hlp file
  11.  */
  12.  
  13. #include "vim.h"
  14. #include "globals.h"
  15. #include "proto.h"
  16. #include "param.h"
  17.  
  18. static long helpfilepos;        /* position in help file */
  19. static FILE *helpfd;            /* file descriptor of help file */
  20.  
  21. #define MAXSCREENS 52            /* one screen for a-z and A-Z */
  22.  
  23.     void
  24. help()
  25. {
  26.     int        c;
  27.     int        eof;
  28.     int        screens;
  29.     int        i;
  30.     long    filepos[MAXSCREENS];    /* seek position for each screen */
  31.     int        screennr;            /* screen number; index == 0, 'c' == 1, 'd' == 2, etc */
  32. #if defined(MSDOS) && !defined(NT)
  33.     char_u    *fnamep;
  34. #endif
  35.  
  36. /*
  37.  * try to open the file specified by the "helpfile" option
  38.  */
  39.     if ((helpfd = fopen((char *)p_hf, READBIN)) == NULL)
  40.     {
  41. #if defined(MSDOS) && !defined(NT)
  42.     /*
  43.      * for MSDOS: try the DOS search path
  44.      */
  45.         fnamep = searchpath("vim.hlp");
  46.         if (fnamep == NULL || (helpfd = fopen((char *)fnamep, READBIN)) == NULL)
  47.         {
  48.             smsg((char_u *)"Sorry, help file \"%s\" and \"vim.hlp\" not found", p_hf);
  49.             return;
  50.         }
  51. #else
  52.         smsg((char_u *)"Sorry, help file \"%s\" not found", p_hf);
  53.         return;
  54. #endif
  55.     }
  56.     helpfilepos = 0;
  57.     screennr = 0;
  58.     for (i = 0; i < MAXSCREENS; ++i)
  59.         filepos[i] = 0;
  60.     State = HELP;
  61.     for (;;)
  62.     {
  63.         screens = redrawhelp();                /* show one or more screens */
  64.         eof = (screens < 0);
  65.         if (!eof && screennr + screens < MAXSCREENS)
  66.             filepos[screennr + screens] = ftell(helpfd);
  67.  
  68.         if ((c = vgetc()) == '\n' || c == '\r' || c == Ctrl('C') || c == ESC)
  69.             break;
  70.  
  71.         if (c == ' ' ||
  72. #ifdef MSDOS
  73.                 (c == K_NUL && vpeekc() == 'Q') ||    /* page down */
  74. #endif
  75.                 c == Ctrl('F'))                        /* one screen forwards */
  76.         {
  77.             if (screennr < MAXSCREENS && !eof)
  78.                 ++screennr;
  79.         }
  80.         else if (c == 'a')                    /* go to first screen */
  81.             screennr = 0;
  82.         else if (c == 'b' ||
  83. #ifdef MSDOS
  84.                 (c == K_NUL && vpeekc() == 'I') ||    /* page up */
  85. #endif
  86.                 c == Ctrl('B'))                    /* go one screen backwards */
  87.         {
  88.             if (screennr > 0)
  89.                 --screennr;
  90.         }
  91.         else if (isalpha(c))                /* go to specified screen */
  92.         {
  93.             if (isupper(c))
  94.                 c = c - 'A' + 'z' + 1;        /* 'A' comes after 'z' */
  95.             screennr = c - 'b';
  96.         }
  97. #ifdef MSDOS
  98.         if (c == K_NUL)
  99.             c = vgetc();
  100. #endif
  101.         for (i = screennr; i > 0; --i)
  102.             if (filepos[i])
  103.                 break;
  104.         fseek(helpfd, filepos[i], 0);
  105.         while (i < screennr)
  106.         {
  107.             while ((c = getc(helpfd)) != '\f' && c != -1)
  108.                 ;
  109.             if (c == -1)
  110.                 break;
  111.             filepos[++i] = ftell(helpfd);    /* store the position just after the '\f' */
  112.         }
  113.         screennr = i;                        /* required when end of file reached */
  114.         helpfilepos = filepos[screennr];
  115.     }
  116.     State = NORMAL;
  117.     fclose(helpfd);
  118.     updateScreen(CLEAR);
  119. }
  120.  
  121. /*
  122.  * redraw the help info for the current position in the help file
  123.  *
  124.  * return the number of screens displayed, or -1 if end of file reached
  125.  */
  126.     int
  127. redrawhelp()
  128. {
  129.     int nextc;
  130.     int col;
  131.     int    line = 0;
  132.     int    screens = 1;
  133.  
  134.     fseek(helpfd, helpfilepos, 0);
  135.     outstr(T_ED);
  136.     (void)set_highlight('h');
  137.     windgoto(0,0);
  138.     while ((nextc = getc(helpfd)) != -1 && (nextc != '\f' || line < Rows - 24))
  139.     {
  140.         if (nextc == Ctrl('B'))            /* begin of standout */
  141.             start_highlight();
  142.         else if (nextc == Ctrl('E'))    /* end of standout */
  143.             stop_highlight();
  144.         else if (nextc == '\f')            /* start of next screen */
  145.         {
  146.             ++screens;
  147.             outchar('\n');
  148.             ++line;
  149.         }
  150.         else
  151.         {
  152.             outchar(nextc);
  153.             if (nextc == '\n')
  154.                 ++line;
  155.         }
  156.     }
  157.     windgoto(0, (int)(Columns - STRLEN(Version) - 1));
  158.     outstrn(Version);
  159.     col = (int)Columns - 52;
  160.     if (col < 0)
  161.         col = 0;
  162.     windgoto((int)Rows - 1, col);
  163.     OUTSTRN("<space = next; return = quit; a = index; b = back>");
  164.     return (nextc == -1 ? -1 : screens);
  165. }
  166.